const { version } = require('../package.json')
const Methods = {
  GET: 'GET',
  POST: 'POST',
  PUT: 'PUT',
  DELETE: 'DELETE'
}
const FileTypes = {
  IMAGE: 'image',
  VIDEO: 'video',
  AUDIO: 'audio'
}
const DataType = ['json', 'text', 'base64', 'arraybuffer']
const DEFAULT_TIMEOUT = 60000
const DEFAULT_DATA_TYPE = 'json'

class Options {
  constructor (url) {
    this.url = url
    this.data = {}
    this.headers = {}
    this.method = Methods.GET
    this.timeout = DEFAULT_TIMEOUT
    this.dataType = DEFAULT_DATA_TYPE
  }

  setUrl (url) {
    this.url = url
    return this
  }

  setData (data) {
    this.data = data || {}
    return this
  }

  setMethod (method) {
    if (Object.keys(Methods).includes(method)) {
      this.method = method || Methods.GET
    }
    return this
  }

  setHeaders (headers) {
    this.headers = headers || {}
    return this
  }

  setTimeout (timeout) {
    this.timeout = timeout || DEFAULT_TIMEOUT
    return this
  }

  setDataType (dataType) {
    if (DataType.includes(dataType)) {
      this.dataType = dataType || DEFAULT_DATA_TYPE
    }
    return this
  }

  request (complete) {
    return new Promise((resolve, reject) => {
      const { url, method, headers, data, dataType } = this
      my.request({
        url,
        method,
        headers,
        data,
        dataType,
        success: res => {
          if (dataType.toLowerCase() === 'json') {
            resolve(res.data)
          } else {
            resolve(res)
          }
        },
        fail: err => {
          reject(err)
        },
        complete
      })
    })
  }

}

class UploadOptions {
  constructor (url) {
    this.url = url
    this.headers = {}
    this.formData = undefined
    this.filePath = ''
    this.fileName = ''
    this.fileType = FileTypes.IMAGE
  }

  setUrl (url) {
    this.url = url
    return this
  }

  setFormData (formData) {
    this.formData = formData || undefined
    return this
  }

  setFile (filePath, fileName, fileType) {
    this.filePath = filePath
    this.fileName = fileName
    this.fileType = fileType || FileTypes.IMAGE
    return this
  }

  setFilePath (filePath) {
    this.filePath = filePath
    return this
  }

  setFileName (fileName) {
    this.fileName = fileName
    return this
  }

  setFileType (fileType) {
    this.fileType = fileType || FileTypes.IMAGE
    return this
  }

  setHeaders (headers) {
    this.headers = headers || {}
    return this
  }

  upload (complete) {
    return new Promise((resolve, reject) => {
      const { url, headers, filePath, fileName, fileType, formData } = this
      my.uploadFile({
        url,
        header: headers,
        filePath, fileName, fileType, formData,
        success: res => {
          const data = res.data
          resolve(typeof data === 'string' && (data.startsWith('{') || data.startsWith('[')) ? JSON.parse(data) : data)
        },
        fail: err => {
          reject(err)
        },
        complete
      })
    })
  }
}

module.exports = {
  version,
  Methods,
  Options,
  FileTypes,
  UploadOptions
}
